package org.tong.security;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.tong.filter.VerificationCodeFilter;

@Configuration
public class MemorySecurityConf extends WebSecurityConfigurerAdapter {

    public MemorySecurityConf() {
        System.out.println(MemorySecurityConf.class.getName() + "\tinit.............");
    }

    /**
     * 用来配置拦截保护的请求，比如什么请求放行，什么请求需要验证
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        // 1.使用Ant风格
        /*http.authorizeRequests()
                .antMatchers("/user/detail").hasAnyRole("USER", "ADMIN")
                .antMatchers("/admin/detail").hasAnyRole("ADMIN")
                .regexMatchers("user/.*").hasAnyRole("USER") //使用正则表达式
                .anyRequest().permitAll()
                // 对没有配置权限的请求允许匿名访问
                .and().anonymous()
                // 使用默认登录页面,启用http基础认证
                .and().formLogin().and().httpBasic();*/
        // 2.使用Spring表达式
       /* http.authorizeRequests()
                .antMatchers("/user/**").access("hasRole('USER') or hasRole('ADMIN')")
                .antMatchers("/admin/**").access("hasAuthority('ROLE_ADMIN') && isFullyAuthenticated()")
                .and().formLogin()
                .and().httpBasic();*/
        // 3. 强制使用HTTPS请求
        http
                .csrf().disable()
                .authorizeRequests().and()
                .requiresChannel().antMatchers("/admin/**").requiresSecure()
                .and().authorizeRequests().antMatchers("/admin/**").hasAnyRole("ADMIN")
                .and().requiresChannel().antMatchers("/", "user/**").requiresInsecure()
                .and().authorizeRequests().antMatchers("/", "/user/**").hasAnyRole("ADMIN", "USER")
                .anyRequest().permitAll()
                .and().formLogin().loginPage("/login/page").permitAll()
                .defaultSuccessUrl("/")
                .and().logout().logoutUrl("/logout").logoutSuccessUrl("/logout/page")
                .and().httpBasic()
                .and().addFilterBefore(new VerificationCodeFilter(), UsernamePasswordAuthenticationFilter.class);

    }

    /**
     * 用来配置用户签名服务，主要是user-details机制，你还可以给予用户赋予角色
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //super.configure(auth);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        // 基于内存配置用户和密码
        auth.inMemoryAuthentication()
                .passwordEncoder(encoder)
                .withUser("admin")
                .password(encoder.encode("admin123"))
                .roles("USER", "ADMIN")
                .and()
                .withUser("user")
                .password(encoder.encode("user123"))
                .roles("USER");
    }

    /**
     * 用来配置Filter链
     *
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }
}
